#include "stdafx.h"
#include "tcp_client.h"
#include "msgpump.h"

#ifndef ASYNCHRONOUS

Client::Client (const string & hostname, unsigned short port)   
{   
    io_service_ = new io_service();   
    socket_ = new tcp::socket(*io_service_);   
  
    tcp::resolver resolver(*io_service_);   
    tcp::resolver::query query(hostname, boost::lexical_cast<string, unsigned short>(port));   
  
    boost::system::error_code ec;   
    tcp::resolver::iterator iter = resolver.resolve(query, ec);   
    tcp::resolver::iterator end;   
  
    // pick the first endpoint   
    if (iter != end && ec == 0)   
    {   
        tcp::endpoint endpoint = *iter;   
        std::cout << "Connecting to: " << endpoint << std::endl;   
  
        socket_->connect(endpoint, ec);   
        if (ec)   
        {   
            std::cerr << "Error: " << ec << std::endl;   
            throw ec;   
        }   
    }   
}   
  
Client::~Client ()   
{   
    delete socket_;   
    delete io_service_;    
}   
  
void Client::send (const string & message)   
{   
    boost::asio::const_buffers_1 request(message.data(), message.size());   
    socket_->send(request);   
}   
  
string Client::recv ()   
{   
    char response[128];   
    size_t num = socket_->receive(boost::asio::buffer(response));   
    if (num > 0)   
    {   
        return string (response, num);   
    }   
  
    return "";   
}   
  
void Client::close ()   
{   
    socket_->close();   
       
}   

//int _tmain(int argc, _TCHAR* argv[])
//{
//	Client client ("localhost", 8100);   
//    std::cout << client.recv() << endl;   
//           
//    string request;   
//  
//    do   
//    {   
//        std::cout << "Request: ";   
//           
//        std::cin >> request;   
//           
//        if (request == "q")   
//            break;   
//  
//        client.send (request);   
//  
//        std::cout << "Response: " << client.recv() << endl;   
//    }   
//    while (true);   
//       
//    client.close();   
//	return 0;
//}

#else

CClientASIO::CClientASIO (const std::string & hostname, unsigned short port,io_service  * io_service_)   
{   
	m_io_service = io_service_;
    m_socket     = new tcp::socket(*m_io_service);
  
    tcp::resolver        resolver(*m_io_service);     
    boost::system::error_code ec;   
	tcp::resolver::query query(hostname, boost::lexical_cast<std::string, unsigned short>(port));   
	tcp::resolver::iterator iter = resolver.resolve(query, ec);   
    tcp::resolver::iterator end;   
  
    // pick the first endpoint   
    if (iter != end && ec == 0)   
    {   
        tcp::endpoint endpoint = *iter;   

		std::cout << "Connecting to: " << endpoint << std::endl;   
  
        m_socket->connect(endpoint, ec); 
		memset(m_data,0,sizeof(m_data));
		m_socket->async_read_some(boost::asio::buffer(m_data,_RECV_BUF_SIZE_),
			boost::bind(&CClientASIO::OnRecv,this,
			boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
        if (ec)   
        {   
            std::cerr << "Error: " << ec << std::endl;   
            throw ec;   
            OutputDebugString(L"[Err]socket connect fail!\n");
        }
        else
        {
            OutputDebugString(L"[Client][Detail]socket connect ok!\n");
        }
    }   
}   
  
CClientASIO::~CClientASIO()   
{   
    delete m_socket;   
    delete m_io_service;
}   
  
void CClientASIO::PostSend(char *data,int nSize) 
{   
	m_socket->async_write_some(boost::asio::buffer(data,nSize),
		boost::bind(&CClientASIO::OnSend,this,
		boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}

bool CClientASIO::OnRecv(const boost::system::error_code& error,size_t bytes_transferred)
{
        if(!error)
        {
			std::string strRecv = (char *)m_data;
			
			std::cout<<strRecv<<std::endl;   

            MSG_PUMP->OnMsg(m_data,bytes_transferred);

			memset(m_data,0,sizeof(m_data));
			m_socket->async_read_some(boost::asio::buffer(m_data,_RECV_BUF_SIZE_),
                boost::bind(&CClientASIO::OnRecv,this,
                boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
        }
        else
        {
            //OnClose(error);

			return false;
        }
		return true;
}

bool CClientASIO::OnSend(const boost::system::error_code& error,size_t bytes_transferred)
{
	std::cout<<"Send Bytes:"<<bytes_transferred<<std::endl;
	if(error)
	{
		OnClose(error);
		return false;
	}
	return true;
}

void CClientASIO::OnClose(const boost::system::error_code& error)
{   
    m_socket->close(); 
}   

//int _tmain(int argc, _TCHAR* argv[])
//{
//	io_service io_service_;
//	CClientASIO c("127.0.0.1", 8100,&io_service_);  
//	std::string strMsg="Hello,World!";
//	c.PostSend(strMsg);
//	io_service_.run();
//           
//	return 0;
//}

#endif